package com.njupt.simulation.utils;

import com.njupt.simulation.entity.Complex;

public class Antenna2101 {
    /**
     *计算天线阵列模型单元方向图的水平辐射方向图
     * @param phi 方位角：-180°~180°
     * @param phi_3db 阵元水平半功率角
     * @param Am 天线前后比
     * @return 阵元水平辐射值(dB)
     */
    public static double calculateHorizontal(double phi , double phi_3db , double Am){
        // 参数验证
        if (phi < -180.0 || phi > 180.0) {
            throw new IllegalArgumentException("参数 'phi' 必须在 -180° 到 180° 之间。当前值: " + phi);
        }
        if (phi_3db <= 0.0) {
            throw new IllegalArgumentException("参数 'phi_3db' 必须大于 0°。当前值: " + phi_3db);
        }
        // 计算 phi / phi_3db 的平方
        double ratio = phi / phi_3db;
        double value = 12 * Math.pow(ratio, 2); // 计算 12 * (phi / phi_3db)^2
        double dBValue = 10 * Math.log10(value); // 转换为分贝

        // 返回 -min[12 * (phi / phi_3db)^2, Am]
        return -Math.min(dBValue, Am);
    }
    /**
     *计算天线阵列模型单元方向图的垂直辐射方向图
     * @param sita 仰角：0°~180°
     * @param sita_3db 阵元垂直半功率角
     * @param SLAv 旁瓣电平极限
     * @return 阵元垂直辐射值
     */
    public static double calculateVector(double sita , double sita_3db ,double SLAv ){
        // 参数验证
        if (sita < 0.0 || sita > 180.0) {
            throw new IllegalArgumentException("参数 'sita' 必须在 0° 到 180° 之间。当前值: " + sita);
        }
        if (sita_3db <= 0.0) {
            throw new IllegalArgumentException("参数 'sita_3db' 必须大于 0°。当前值: " + sita_3db);
        }

        // 计算 (sita - 90) / sita_3db 的平方
        double ratio = (sita - 90) / sita_3db;
        double value = 12 * Math.pow(ratio, 2); // 计算 12 * ((sita - 90) / sita_3db)^2
        double dBValue = 10 * Math.log10(value); // 转换为分贝
        // 返回 -min[12 * ((sita - 90) / sita_3db)^2, SLAv]
        return -Math.min(dBValue , SLAv);
    }
    /**
     * 计算单个元件方向图的辐射值
     * @param Gmax 天线阵元增益
     * @param Am 天线前后比
     * @return 单个元件辐射值
     */
    public static double calculateAe(double phi , double phi_3db , double Am ,double Gmax , double sita , double sita_3db ,double SLAv ){
        return Gmax-Math.min(-(calculateHorizontal(phi,phi_3db,Am)+calculateVector(sita,sita_3db,SLAv)),Am);
    }

    /**
     *计算天线增益
     * @param phi 方位角：-180°~180°
     * @param phi_3db 阵元水平半功率角
     * @param Am 天线前后比
     * @param Gmax 天线阵元增益
     * @param sita 仰角：0°~180°
     * @param sita_3db 阵元垂直半功率角
     * @param SLAv 旁瓣电平极限
     * @param dv_lamada 垂直方向的阵元间距
     * @param dh_lamada 水平方向的阵元间距
     * @param n 天线阵列配置的列
     * @param m 天线阵列配置的行
     * @param sita_etilt 电子下倾角
     * @param phi_escan 电子水平转向角
     * @return 天线增益值
     */
    public static double G(double phi, double phi_3db, double Am,
                           double Gmax, double sita, double sita_3db, double SLAv,
                           double dv_lamada, double dh_lamada, int n, int m,
                           double sita_etilt, double phi_escan) {
        // 参数验证
        if (sita < 0.0 || sita > 180.0) {
            throw new IllegalArgumentException("参数 'sita' 必须在 0° 到 180° 之间。当前值: " + sita);
        }
        if (sita_3db <= 0.0) {
            throw new IllegalArgumentException("参数 'sita_3db' 必须大于 0°。当前值: " + sita_3db);
        }
        if (phi < -180.0 || phi > 180.0) {
            throw new IllegalArgumentException("参数 'phi' 必须在 -180° 到 180° 之间。当前值: " + phi);
        }
        if (phi_3db <= 0.0) {
            throw new IllegalArgumentException("参数 'phi_3db' 必须大于 0°。当前值: " + phi_3db);
        }

        // 计算单个阵元的辐射值
        double Asingle = calculateAe(phi, phi_3db, Am, Gmax, sita, sita_3db, SLAv);

        // 初始化复数总和为零
        Complex sum = Complex.ZERO;

        // 遍历每个天线元素
        for (int mi = 1; mi <= m; mi++) {
            for (int ni = 1; ni <= n; ni++) {
                // 计算每个天线元素的转向因子和重量因子
                double angleV = 2 * Math.PI * ((ni - 1) * dv_lamada * Math.cos(Math.toRadians(sita))
                        + (mi - 1) * dh_lamada * Math.sin(Math.toRadians(sita)) * Math.sin(Math.toRadians(phi)));
                Complex v = new Complex(Math.cos(angleV), Math.sin(angleV));

                double angleW = 2 * Math.PI * ((ni - 1) * dv_lamada * Math.sin(Math.toRadians(sita_etilt))
                        - (mi - 1) * dh_lamada * Math.cos(Math.toRadians(sita_etilt)) * Math.sin(Math.toRadians(phi_escan)));
                Complex w = new Complex(Math.cos(angleW), Math.sin(angleW)).scale(1 / Math.sqrt(n * m));

                sum = sum.add(v.multiply(w));
            }
        }

        // 计算增益
        double powerSum = Math.pow(sum.magnitude(), 2);
        double adjustedGain = Asingle + 10 * Math.log10(1+(powerSum-1));

        return adjustedGain;
    }

//    // 计算 v_mn 的方法
//    public static Complex calculateVmN(int m, int n, double dV_lambda, double dH_lambda,double sita, double phi) {
//        double term1 = (n - 1) * dV_lambda * Math.cos(Math.toRadians(sita));
//        double term2 = (m - 1) * dH_lambda * Math.sin(Math.toRadians(sita)) * Math.sin(Math.toRadians(phi));
//        Complex result = Complex.fromPolar(1, 2 * Math.PI * (term1 + term2)); // 使用复数类创建复数
//        return result;
//    }
//
//    // 计算 w_mn 的方法
//    public static Complex calculateWmN(int m, int n, double dV_lambda, double dH_lambda, double thetaElit, double phiScan, int N_H, int N_V) {
//
//        double term1 = (n - 1) * dV_lambda * Math.sin(Math.toRadians(thetaElit));
//        double term2 = (m - 1) * dH_lambda * Math.cos(Math.toRadians(thetaElit)) * Math.sin(Math.toRadians(phiScan));
//        double normalization = 1 / Math.sqrt(N_H * N_V);
//        Complex result = Complex.fromPolar(normalization, 2 * Math.PI * (term1 - term2));
//        return result;
//    }
//
//    // 计算最终增益 A_A
//    public static double calculateA_A(int N_H, int N_V, Complex[][] w, Complex[][] v) {
//        int rho = 1;
//        Complex sum = Complex.ZERO;
//        for (int m = 0; m < N_H; m++) {
//            for (int n = 0; n < N_V; n++) {
//                sum = sum.add(w[m][n].multiply(v[m][n])); // 使用复数类进行加法和乘法
//            }
//        }
//        // 计算增益
//        double powerSum = Math.pow(sum.magnitude(), 2);  // 这里计算复数模的平方
//        return 10 * Math.log10(1 + rho * (powerSum - 1));
//    }
//
//    //计算最终增益G
//    public static double G(double phi, double phi_3db, double Am,
//                           double Gmax, double sita, double sita_3db, double SLAv,
//                           int N_H, int N_V,Complex[][] w, Complex[][] v
//                           ) {
//        double Asingle = calculateAe(phi, phi_3db, Am, Gmax, sita, sita_3db, SLAv);
//        double A_A = calculateA_A(N_H, N_V, w, v);
//        return Asingle +  A_A;
//    }

    public static void main(String[] args) {
        double phi = 11.0;
        double phi_3db = 65.0;
        double Am = 30.0;
        double Gmax = 5.0;
        double sita = 91.0;
        double sita_3db = 65.0;
        double SLAv = 30.0;
        double dv_lamada = 0.5;
        double dh_lamada = 0.5;
        int n = 4;
        int m = 4;
        double sita_etilt = 10.0;
        double phi_escan = 40.0;
        double result = G(phi, phi_3db, Am, Gmax, sita, sita_3db, SLAv, dv_lamada, dh_lamada, n, m, sita_etilt, phi_escan);
        System.out.println("The result is: " + result);

//        int N_H = 256; // 水平方向的天线数量
//        int N_V = 256; // 垂直方向的天线数量
//
//        double dV_lambda = 0.5; // 垂直方向间距与波长的比
//        double dH_lambda = 0.5; // 水平方向间距与波长的比
//        double sita = 105; // 主波束的仰角
//        double phi = 15; // 主波束的方位角
//        double thetaEtilt = 10; // 电子倾角
//        double phiScan = 40; // 扫描方位角
//
//        double phi_3db = 65; // 3dB波束宽度（方位）
//        double Am = 30;
//        double Gmax = 5;
//        double sita_3db = 65; // 3dB波束宽度（仰角）
//        double SLAv = 30; // 侧瓣抑制级别
//
//        // 初始化 w 和 v 数组
//        Complex[][] wArray = new Complex[N_H][N_V];
//        Complex[][] vArray = new Complex[N_H][N_V];
//        for (int m = 0; m < N_H; m++) {
//            for (int n = 0; n < N_V; n++) {
//                wArray[m][n] = calculateWmN(m + 1, n + 1, dV_lambda, dH_lambda, thetaEtilt, phiScan, N_H, N_V);
//                vArray[m][n] = calculateVmN(m + 1, n + 1, dV_lambda, dH_lambda, sita, phi);
//            }
//        }
//
//        // 计算增益
//        double totalGain = G(phi, phi_3db, Am, Gmax, sita, sita_3db, SLAv, N_H, N_V, wArray, vArray);
//        System.out.println("Total Array Gain: " + totalGain);
//
//}
    }
}


